import { Task, UserTask, PointRecord, PointAccount, TaskStatistics } from '../models/Task';
import { PatientProfile } from '../models/User';
import { Storage } from '@kit.StorageKit';

// 任务管理服务类
export class TaskService {
  private static instance: TaskService;
  private storageKeyPrefix = 'task_';
  private pointsKeyPrefix = 'points_';

  // 单例模式
  public static getInstance(): TaskService {
    if (!TaskService.instance) {
      TaskService.instance = new TaskService();
    }
    return TaskService.instance;
  }

  // 创建任务
  async createTask(task: Omit<Task, 'id' | 'createdAt'>): Promise<Task | null> {
    try {
      const newTask: Task = {
        ...task,
        id: Date.now().toString() + Math.random().toString(36).substr(2, 9),
        createdAt: new Date()
      };
      
      // 获取所有任务
      const tasks = await this.getAllTasks();
      tasks.push(newTask);
      
      // 保存任务
      await Storage.setOrCreate(this.storageKeyPrefix + 'all', JSON.stringify(tasks));
      
      return newTask;
    } catch (error) {
      console.error('创建任务失败:', error);
      return null;
    }
  }

  // 获取所有任务
  async getAllTasks(): Promise<Task[]> {
    try {
      const tasksData = await Storage.get(this.storageKeyPrefix + 'all');
      return tasksData ? JSON.parse(tasksData) : [];
    } catch (error) {
      console.error('获取任务列表失败:', error);
      return [];
    }
  }

  // 获取特定类型的任务
  async getTasksByType(type: string): Promise<Task[]> {
    try {
      const tasks = await this.getAllTasks();
      return tasks.filter(task => task.type === type);
    } catch (error) {
      console.error('获取特定类型任务失败:', error);
      return [];
    }
  }

  // 为用户分配任务
  async assignTaskToUser(userId: string, taskId: string): Promise<UserTask | null> {
    try {
      // 获取任务
      const tasks = await this.getAllTasks();
      const task = tasks.find(t => t.id === taskId);
      
      if (!task) {
        throw new Error('任务不存在');
      }
      
      // 计算截止日期
      const dueDate = new Date();
      switch (task.frequency) {
        case 'daily':
          dueDate.setDate(dueDate.getDate() + 1);
          break;
        case 'weekly':
          dueDate.setDate(dueDate.getDate() + 7);
          break;
        case 'monthly':
          dueDate.setMonth(dueDate.getMonth() + 1);
          break;
      }
      
      // 创建用户任务
      const userTask: UserTask = {
        id: Date.now().toString() + Math.random().toString(36).substr(2, 9),
        taskId,
        userId,
        status: 'pending',
        assignedDate: new Date(),
        dueDate,
        progress: 0
      };
      
      // 保存用户任务
      const userTasks = await this.getUserTasks(userId);
      userTasks.push(userTask);
      await Storage.setOrCreate(this.storageKeyPrefix + 'user_' + userId, JSON.stringify(userTasks));
      
      return userTask;
    } catch (error) {
      console.error('分配任务失败:', error);
      return null;
    }
  }

  // 获取用户任务
  async getUserTasks(userId: string, status?: string): Promise<UserTask[]> {
    try {
      const userTasksData = await Storage.get(this.storageKeyPrefix + 'user_' + userId);
      let userTasks: UserTask[] = userTasksData ? JSON.parse(userTasksData) : [];
      
      // 如果指定了状态，进行过滤
      if (status) {
        userTasks = userTasks.filter(task => task.status === status);
      }
      
      return userTasks;
    } catch (error) {
      console.error('获取用户任务失败:', error);
      return [];
    }
  }

  // 更新任务进度
  async updateTaskProgress(taskId: string, userId: string, progress: number): Promise<boolean> {
    try {
      const userTasks = await this.getUserTasks(userId);
      const taskIndex = userTasks.findIndex(t => t.id === taskId);
      
      if (taskIndex === -1) {
        return false;
      }
      
      // 更新进度
      userTasks[taskIndex].progress = Math.max(0, Math.min(100, progress));
      
      // 如果进度达到100%，标记为完成并发放积分
      if (progress >= 100 && userTasks[taskIndex].status !== 'completed') {
        userTasks[taskIndex].status = 'completed';
        userTasks[taskIndex].completedDate = new Date();
        
        // 发放积分
        const tasks = await this.getAllTasks();
        const task = tasks.find(t => t.id === userTasks[taskIndex].taskId);
        if (task) {
          await this.addPoints(userId, task.points, 'task', task.id, `完成任务: ${task.title}`);
          userTasks[taskIndex].pointsEarned = task.points;
        }
      }
      
      // 保存更新后的任务
      await Storage.setOrCreate(this.storageKeyPrefix + 'user_' + userId, JSON.stringify(userTasks));
      
      return true;
    } catch (error) {
      console.error('更新任务进度失败:', error);
      return false;
    }
  }

  // 标记任务为失败
  async markTaskAsFailed(taskId: string, userId: string): Promise<boolean> {
    try {
      const userTasks = await this.getUserTasks(userId);
      const taskIndex = userTasks.findIndex(t => t.id === taskId);
      
      if (taskIndex === -1) {
        return false;
      }
      
      userTasks[taskIndex].status = 'failed';
      await Storage.setOrCreate(this.storageKeyPrefix + 'user_' + userId, JSON.stringify(userTasks));
      
      return true;
    } catch (error) {
      console.error('标记任务为失败失败:', error);
      return false;
    }
  }

  // 添加积分
  async addPoints(userId: string, points: number, type: string, sourceId?: string, description?: string): Promise<boolean> {
    try {
      // 创建积分记录
      const pointRecord: PointRecord = {
        id: Date.now().toString() + Math.random().toString(36).substr(2, 9),
        userId,
        points,
        type: type as 'task' | 'reward' | 'penalty',
        sourceId,
        timestamp: new Date(),
        description: description || `${type}积分`
      };
      
      // 获取用户积分账户
      let pointAccount = await this.getPointAccount(userId);
      if (!pointAccount) {
        pointAccount = {
          userId,
          totalPoints: 0,
          level: 1,
          pointsHistory: [],
          lastUpdated: new Date()
        };
      }
      
      // 更新积分账户
      pointAccount.totalPoints += points;
      pointAccount.pointsHistory.unshift(pointRecord);
      pointAccount.lastUpdated = new Date();
      
      // 更新等级
      pointAccount.level = this.calculateLevel(pointAccount.totalPoints);
      
      // 保存积分账户
      await Storage.setOrCreate(this.pointsKeyPrefix + userId, JSON.stringify(pointAccount));
      
      return true;
    } catch (error) {
      console.error('添加积分失败:', error);
      return false;
    }
  }

  // 获取用户积分账户
  async getPointAccount(userId: string): Promise<PointAccount | null> {
    try {
      const accountData = await Storage.get(this.pointsKeyPrefix + userId);
      return accountData ? JSON.parse(accountData) : null;
    } catch (error) {
      console.error('获取积分账户失败:', error);
      return null;
    }
  }

  // 计算用户等级
  private calculateLevel(totalPoints: number): number {
    // 简单的等级计算逻辑
    if (totalPoints < 100) return 1;
    if (totalPoints < 300) return 2;
    if (totalPoints < 600) return 3;
    if (totalPoints < 1000) return 4;
    if (totalPoints < 1500) return 5;
    return 6;
  }

  // 获取任务统计
  async getTaskStatistics(userId: string): Promise<TaskStatistics> {
    try {
      const userTasks = await this.getUserTasks(userId);
      const completedTasks = userTasks.filter(t => t.status === 'completed').length;
      const totalTasks = userTasks.length;
      const completionRate = totalTasks > 0 ? (completedTasks / totalTasks) * 100 : 0;
      
      // 计算获得的总积分
      const pointsEarned = userTasks
        .filter(t => t.pointsEarned)
        .reduce((sum, t) => sum + (t.pointsEarned || 0), 0);
      
      // 计算连续完成天数
      const streakDays = this.calculateStreakDays(userTasks);
      
      // 计算分类统计
      const categoryStats = this.calculateCategoryStats(userTasks);
      
      return {
        userId,
        completedTasks,
        totalTasks,
        completionRate,
        pointsEarned,
        streakDays,
        lastCompletedDate: this.getLastCompletedDate(userTasks),
        categoryStats
      };
    } catch (error) {
      console.error('获取任务统计失败:', error);
      return {
        userId,
        completedTasks: 0,
        totalTasks: 0,
        completionRate: 0,
        pointsEarned: 0,
        streakDays: 0,
        categoryStats: []
      };
    }
  }

  // 计算连续完成天数
  private calculateStreakDays(userTasks: UserTask[]): number {
    // 获取所有已完成任务的日期，去重并排序
    const completedDates = Array.from(new Set(
      userTasks
        .filter(t => t.status === 'completed' && t.completedDate)
        .map(t => new Date(t.completedDate!).toDateString())
    )).sort((a, b) => new Date(b).getTime() - new Date(a).getTime());
    
    if (completedDates.length === 0) return 0;
    
    let streak = 1;
    const today = new Date().toDateString();
    const yesterday = new Date(Date.now() - 24 * 60 * 60 * 1000).toDateString();
    
    // 检查最近的完成日期是否是今天或昨天
    if (completedDates[0] !== today && completedDates[0] !== yesterday) {
      return 0;
    }
    
    // 计算连续天数
    for (let i = 1; i < completedDates.length; i++) {
      const currentDate = new Date(completedDates[i - 1]);
      const prevDate = new Date(completedDates[i]);
      const diffTime = currentDate.getTime() - prevDate.getTime();
      const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
      
      if (diffDays === 1) {
        streak++;
      } else {
        break;
      }
    }
    
    return streak;
  }

  // 计算分类统计
  private calculateCategoryStats(userTasks: UserTask[]): any[] {
    // 简化版本，实际应用中需要关联任务类型
    return [
      { type: 'diet', completed: 0, total: 0, percentage: 0 },
      { type: 'exercise', completed: 0, total: 0, percentage: 0 },
      { type: 'medication', completed: 0, total: 0, percentage: 0 },
      { type: 'emotion', completed: 0, total: 0, percentage: 0 }
    ];
  }

  // 获取最后完成日期
  private getLastCompletedDate(userTasks: UserTask[]): Date | undefined {
    const completedTasks = userTasks.filter(t => t.status === 'completed' && t.completedDate);
    if (completedTasks.length === 0) return undefined;
    
    return new Date(Math.max(...completedTasks.map(t => new Date(t.completedDate!).getTime())));
  }

  // 初始化默认任务库
  async initializeDefaultTasks(): Promise<void> {
    try {
      const existingTasks = await this.getAllTasks();
      if (existingTasks.length > 0) {
        console.log('任务库已存在，跳过初始化');
        return;
      }
      
      const defaultTasks: Omit<Task, 'id' | 'createdAt'>[] = [
        {
          type: 'diet',
          title: '每日饮水2000ml',
          description: '保持充足的水分摄入，促进新陈代谢',
          difficulty: 'easy',
          duration: 1,
          points: 10,
          frequency: 'daily',
          recommendedFor: ['高血压', '糖尿病']
        },
        {
          type: 'exercise',
          title: '30分钟有氧运动',
          description: '进行散步、慢跑、游泳等有氧运动，改善心肺功能',
          difficulty: 'medium',
          duration: 30,
          points: 20,
          frequency: 'daily',
          recommendedFor: ['高血压', '糖尿病', '心脏病']
        },
        {
          type: 'medication',
          title: '按时服药',
          description: '按照医生的建议，按时按量服用药物',
          difficulty: 'easy',
          duration: 5,
          points: 15,
          frequency: 'daily',
          recommendedFor: ['高血压', '糖尿病', '心脏病']
        },
        {
          type: 'emotion',
          title: '冥想放松10分钟',
          description: '通过冥想缓解压力，保持良好心态',
          difficulty: 'easy',
          duration: 10,
          points: 10,
          frequency: 'daily',
          recommendedFor: ['高血压', '抑郁症']
        },
        {
          type: 'diet',
          title: '控制盐分摄入',
          description: '每日盐分摄入不超过5克，预防高血压',
          difficulty: 'medium',
          duration: 5,
          points: 15,
          frequency: 'daily',
          recommendedFor: ['高血压']
        },
        {
          type: 'exercise',
          title: '每周两次力量训练',
          description: '进行适度的力量训练，增强肌肉力量',
          difficulty: 'hard',
          duration: 45,
          points: 30,
          frequency: 'weekly',
          recommendedFor: ['糖尿病', '骨质疏松']
        }
      ];
      
      // 创建默认任务
      for (const task of defaultTasks) {
        await this.createTask(task);
      }
      
      console.log('默认任务库初始化完成');
    } catch (error) {
      console.error('初始化默认任务库失败:', error);
    }
  }
}